home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / gui4cli / ext / lvformat / lvformat.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  10KB  |  309 lines

  1.  
  2. /***********************************************************************
  3. *
  4. *    LVFormat.c by D. Keletsekis (7/10/98) - dck@hol.gr
  5. *
  6. *    This program was made to be used with the CedBar.gc gui, a icon
  7. *    bar for the CygnusEd editor. It can, however, be used anywhere
  8. *    else too, if you need any of it's funtions.
  9. *
  10. *    It creates a port named "LVFormat" and will sit around waiting
  11. *    for commands sent from Gui4Cli using the CALL command. It will
  12. *    then perform whatever action is required, on the CURRENT listview.
  13. *    
  14. *    These are the commands you can CALL from Gui4Cli :
  15. *
  16. *    Indent  [string]
  17. *    - Will indent the current listview by whatever "string"
  18. *      contains. (Optional - default is 3 spaces).
  19. *      ex: CALL LVFormat INDENT ">>>"  ; indent by 3 > thingies..
  20. *
  21. *    UnIndent
  22. *    - Will find the minimum indentation and will move all text
  23. *      in by that much.
  24. *
  25. *    AGClean
  26. *    - Will remove all AmigaGuide formating from the current LV.
  27. *
  28. *    WRAP [Length] [Justify] [Header]
  29. *    - Will wrap the selected text. The wraping is intelligent
  30. *      in that it will try to figure out your indentations and
  31. *      wrap the text so that they remain as they were.
  32. *    - The options you can give are :
  33. *      Length  - The length that you want the lines wraped to. The
  34. *            default, if you give weird values, is 60.
  35. *      Justify - This must be either "" (i.e. nothing) or :
  36. *            JUST   - meaning justify the text by adding extra 
  37. *                     spaces to make up the line length.
  38. *            UNJUST - remove all these extra spaces.
  39. *            CENTER - center the text (automatically unjust)
  40. *            RESET  - remove all extra spacing & indentations.
  41. *      Header  - a string of characters that wrap should consider
  42. *            as part of the line header. This is usefull for
  43. *            wrapping email messages etc, by giving ">/" or
  44. *            whatever your mailer uses. Spaces are always in.
  45. *
  46. ************************************************************************/
  47. // define this for faster exec calls
  48. #define __USESYSBASE
  49.  
  50. #include <exec/exec.h>
  51. #include <exec/execbase.h>
  52. #include <exec/memory.h>
  53. #include <dos/dosextens.h>
  54. #include <dos/rdargs.h>
  55. #include <dos/dostags.h>
  56. #include <string.h>
  57. #include <stdio.h>
  58. #include <ctype.h>
  59. #include <dos.h>
  60. #include <proto/dos.h>
  61. #include <proto/exec.h>
  62. #include <graphics/text.h>
  63.  
  64. // the Gui4Cli include file
  65. #include <Gui4Cli.h>    // use "Gui4Cli.h" if you keep it in same dir
  66.  
  67. // declare a version string (if you want..)
  68. static const char VERSION[] = "\0$VER: LVFormat 1.0 (D.Keletsekis 15/9/98)";
  69.  
  70. // the prototypes - other includes at end of file..
  71. #include "lvformat_protos.h"
  72.  
  73. // ===============================================================
  74. //     MAIN() - note there is no need for a main() function
  75. //    The program starts at the 1st function it finds, which
  76. //    can be any name..
  77. // ===============================================================
  78.  
  79. LONG anyname(void)
  80. {
  81.    struct ExecBase *SysBase = (*((struct ExecBase **) 4));
  82.    struct DosLibrary *DOSBase=NULL;
  83.    struct Process *myself = (struct Process *)(SysBase->ThisTask);
  84.  
  85.    struct MsgPort *myport=NULL;            // our port
  86.    struct g4cmsg  *msg;    // Gui4Cli message pointer
  87.    int    rc = 10;         // return code
  88.    LONG   stayalive = 1;   // Quit counter
  89.    BOOL   msgreplied;      // flag
  90.    LONG   num=60;       // default wrap length
  91.    SHORT  just=0;       // justify flag
  92.  
  93.    // -------------------- open the dos library or die..
  94.  
  95.    if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36L)))
  96.    {   myself->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
  97.        goto endprog;
  98.    }
  99.  
  100.    // --------------------- Open message port or die..
  101.  
  102.    if (!(myport = openport ("LVFormat", SysBase, DOSBase)))
  103.    {   PutStr ("Couldn't open LVFormat port!\n");
  104.        goto endprog;
  105.    }
  106.  
  107.    // ---------------------- Main wait() & process loop
  108.  
  109.    while (stayalive > 0)
  110.    {
  111.       WaitPort (myport);
  112.       msg = (struct g4cmsg *)GetMsg(myport);
  113.       msgreplied = 0;  // flag that message is outstanding
  114.  
  115.       // check that the message is like we expect it..
  116.       if ((msg->magic != 392001) || (msg->type != GM_COMMAND) || (!msg->gcmain) || (!msg->com))
  117.       {   msg->res = 20;  // indicate error
  118.           goto endloop;   // skip message
  119.       }
  120.       
  121.       // --------------- Parse & execute the commands..
  122.       // The command name is in msg->com and it's already converted
  123.       // into upper case by Gui4Cli.
  124.  
  125.       else if (!strcmp(msg->com, "INDENT"))        // Indent [IndentString]
  126.       {
  127.          // if they sent us an argument..
  128.          if (msg->args[0]) 
  129.             indentlist (msg->gcmain, msg->args[0], SysBase, DOSBase);
  130.          else // default = indent by 3 spaces
  131.             indentlist (msg->gcmain, "   ", SysBase, DOSBase);
  132.       }
  133.  
  134.       else if (!strcmp(msg->com, "UNINDENT"))      // remove all leading spaces
  135.       {
  136.            unindentlist (msg->gcmain, SysBase, DOSBase);
  137.       }
  138.  
  139.       else if (!strcmp(msg->com, "AGCLEAN"))       // clear amiga guide stuff
  140.       {
  141.            agclean (msg->gcmain, SysBase, DOSBase);
  142.       }
  143.  
  144.       // WRAP [LineLength] [JUST/UNJUST] [HeaderCharacters]
  145.       else if (!strcmp(msg->com, "WRAP"))
  146.       {
  147.            // get wrap length (default = 60)
  148.            if (msg->args[0])
  149.                if ((StrToLong(msg->args[0], &num)) <= 0) num = 60;
  150.  
  151.            // get justification mode (just/unjust or nothing)
  152.            if (msg->args[1])
  153.            {   makeupper(msg->args[1]); 
  154.            just=0;
  155.                if      (!strcmp(msg->args[1], "JUST"))   just = 1;
  156.                else if (!strcmp(msg->args[1], "UNJUST")) just = 2;
  157.                else if (!strcmp(msg->args[1], "CENTER")) just = 3;
  158.                else if (!strcmp(msg->args[1], "RESET"))  just = 4;
  159.            }
  160.  
  161.        // args[2] contains the header chars, if any.
  162.            rewrap (msg->gcmain, num, msg->args[2], just, SysBase, DOSBase);
  163.       }
  164.  
  165.       // Quiting :
  166.       // A gui which wants to use us will "Register", so we ++stayalive
  167.       // and quit only when all registered guis have told us to quit.
  168.       else if (!strcmp(msg->com, "QUIT"))               // asked to quit
  169.            --stayalive;
  170.       else if (!strcmp(msg->com, "REGISTER"))           // add a life
  171.            ++stayalive;
  172.  
  173.       endloop:
  174.       if (!msgreplied) ReplyMsg ((struct Message *)msg);
  175.  
  176.    }  // end of main while(stayalive) loop
  177.  
  178.    rc = 0; // everything ok..
  179.  
  180.    // ---------------------- END PROG - CLEAN UP
  181.  
  182.    endprog :
  183.    if (myport) closeport (myport, SysBase, DOSBase);
  184.    if (DOSBase) CloseLibrary((struct Library *)DOSBase);
  185.    return (rc);
  186. }
  187.  
  188. // ================================================================
  189. //     create a new public message port
  190. // ================================================================
  191.  
  192. struct MsgPort *openport (char *portname, struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  193. {
  194.    struct MsgPort *port=NULL;
  195.  
  196.    Forbid ();
  197.    if ((port = FindPort(portname)) != NULL)  
  198.    {    // if port already exists - return NULL
  199.         port = NULL;
  200.    }
  201.    else
  202.         port = CreatePort (portname, 0);
  203.    Permit();
  204.  
  205.    return (port);
  206. }
  207.  
  208. // ================================================================
  209. //     free a public message port
  210. // ================================================================
  211.  
  212. void closeport (struct MsgPort *port, struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  213. {
  214.    struct Message *msg;
  215.  
  216.    Forbid ();
  217.    // empty port
  218.    while (msg = GetMsg (port))
  219.           ReplyMsg (msg);
  220.    // remove port name since it's a public msg port
  221.    if (port->mp_Node.ln_Name)
  222.           RemPort (port);
  223.    // delete port
  224.    DeleteMsgPort (port);
  225.    Permit ();
  226. }
  227.  
  228. // ==============================================================
  229. // Send a message, wait for reply.. 
  230. // -->> return 0 for OK or error code otherwise
  231. // - portname = the name of Gui4Cli message port (usually Gui4Cli)
  232. // - type     = GM_LOCK, GM_UNLOCK, GM_COMMAND etc..
  233. // - command  = the command line or NULL
  234. // ==============================================================
  235.  
  236. sendmsg (UBYTE *portname, LONG type, UBYTE *command,
  237.      struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  238. {
  239.    struct Process *myself = (struct Process *)(SysBase->ThisTask);
  240.    struct MsgPort *gcport, *myport;
  241.    str